#!/bin/sh
# - runtime
# - seed
# - number

## perf_fuzzer is a system call fuzzer specifically designed
## to find flaws in the complex Linux perf_event system call interface.
## See: https://github.com/deater/perf_event_tests/tree/master/fuzzer

. $LKP_SRC/lib/env.sh
. $LKP_SRC/lib/reproduce-log.sh
. $LKP_SRC/lib/debug.sh

cd $BENCHMARK_ROOT/perf_event_tests/fuzzer || die "can not find fuzzer dir"

# Check parameters
[ -z "$number" ] && [ -z "$runtime" ] && die "number and runtime can not both be empty "

# Generate seed
[ -z "$seed" ] && {
	seed_source="$tbox_group/$rootfs/$kconfig"

	if has_cmd cksum; then
		seed=$(echo "$seed_source" | cksum)
		seed=${seed%% *}
	else
		seed=$(echo "$seed_source" | md5sum | cut -c1-5)
		seed=$(( 0x$seed ))
	fi

	echo "Seeding perf-fuzzer by $seed based on $seed_source"
}

echo "glibc version $(ldd --version | head -1)"

# Run test
opt="-r $seed"
[ -n "$number" ] && opt="$opt -s $number"

# Wait test finish or timeout
if [ -n "$runtime" ]; then
	log_cmd timeout $runtime ./perf_fuzzer $opt
	exit_status=$?

	if [ $exit_status -eq 124 ]; then
		echo "perf fuzzer test is timeout"
		exit $exit_status
	else
		echo "perf fuzzer test exits with status $exit_status"
		# It's expected that fuzzer exits with fail status like 134 due to
		#	buffer overflow detected ***: terminated
		# The exit_fail in last_state doesn't mean much (like trigger a valuable
		# bisection), so always exit 0 if fuzzer exits itself.
		exit 0
	fi
else
	log_cmd ./perf_fuzzer $opt &
	pid=$!

	wait "$pid" 2>&1
fi
